package main

import (
	"fmt"
	"sync"
)

// 只支持 int 即可。

type MyMap struct {
	sync.Mutex
	dirty map[interface{}]interface{}
}

func (m *MyMap) Load(key interface{}) (value interface{}, ok bool) {
	m.Lock()
	defer m.Unlock()
	value, ok = m.dirty[key]
	return value, ok
}

func (m *MyMap) Store(key, value interface{}) {
	m.Lock()
	defer m.Unlock()
	if m.dirty == nil {
		m.dirty = make(map[interface{}]interface{})
	}
	m.dirty[key] = value
}

func (m *MyMap) Delete(key interface{}) {
	m.Lock()
	defer m.Unlock()
	delete(m.dirty, key)
}

func (m *MyMap) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {
	m.Lock()
	defer m.Unlock()
	v, ok := m.dirty[key]
	if ok {
		return v, true
	} else {
		m.dirty[key] = value
		return value, false
	}
}

func (m *MyMap) LoadAndDelete(key interface{}) (value interface{}, loaded bool) {
	m.Lock()
	defer m.Unlock()
	v, ok := m.dirty[key]
	if ok {
		delete(m.dirty, key)
		return v, true
	} else {
		return nil, false
	}
}

func main() {
	m := MyMap{}

	if value, ok := m.Load("1"); ok {
		fmt.Printf("load value: %v \n", value)
	} else {
		fmt.Println("load not value")
	}
	m.Store("1", 1)
	m.Delete("1")
	if value, ok := m.LoadOrStore("1", 2); ok {
		fmt.Printf("load or store %v \n", value)
	} else {
		fmt.Println("not load or store")
	}

	if value, ok := m.LoadOrStore("2", 2); ok {
		fmt.Printf("set load or store %v \n", value)
	} else {
		fmt.Printf("set load or store not value %v \n", value)
	}

	if value, ok := m.LoadAndDelete("2"); ok {
		fmt.Printf("load and delete %v \n", value)
	} else {
		fmt.Printf("load and delete not value %v \n", value)
	}

	if value, ok := m.LoadAndDelete("2"); ok {
		fmt.Printf("load and delete %v \n", value)
	} else  {
		fmt.Printf("load and delete not value %v \n", value)
	}

}
